#pragma once

#include "Serializable.h"
#include "Vectors.h"
#include "PeopleData.h"
#include "StlStringAndStreams.h"

class ServiceProvider;
class ZStream;

class PeopleManager:public Serializable
{
public:
	PeopleManager(ServiceProvider* const i_sp);
	~PeopleManager();

	void				Clear();
	void				Initialize();

	People*				GetNewPeople(const bool i_isPlayer);
	People*				CreateNewPeople(const bool i_isEmpty, const bool i_isBusy, const bool i_isPlayer);
	void				CreateFreePeople(const unsigned int i_players, const unsigned int i_trainers);
	
	void				ChangePeopleRole(People* i_people, const int i_role);

	void				Ingage(People* i_people, const bool i_isplayer);
	void				Sell(People* i_people, const bool i_isplayer);

	void				Update();
	void				EndSeasonUpdate(const bool i_doNotPrompt, STD::stringstream& o_message);

	void				HandleBankrupt(Team* const io_bankruptTeam);

	const PeopleVec&	GetBusyVec(const bool i_isPlayer) const;
	const PeopleVec&	GetFreeVec(const bool i_isPlayer, const size_t i_minimumFree);
	const PeopleVec&	GetFreeVec(const bool i_isPlayer) const;
	const PeopleVec&	GetHofVec() const;
	People*				GetPeopleFromID(const int i_peopleID, const int i_status = StatusPlayerOrTrainer);

	size_t				GetLastID() const;
	size_t				GetNewID();

	void				CreateHistoryEntry(People* i_people);

	virtual	ZStream&	Serialize(ZStream& o_stream) const;
	virtual ZStream&	Deserialize(ZStream& i_stream);

	void				SerializePeopleArray(ZStream& o_stream, const STL::string& i_tag, const PeopleVec& i_peopleArray) const;
	void				DeserializePeopleArray(ZStream& i_stream, PeopleVec& o_peopleArray);

private:
	PeopleManager(const PeopleManager&);
	PeopleManager& operator=(const PeopleManager&);

	void GenerateNewSlot(const unsigned int i_size, const bool i_isPlayer);
	void PlayersBecomeTrainers(PeopleVec& io_retiringPlayers, PeopleVec& o_playerBecomeTrainer);
	void ShrinkHof(PeopleVec& io_retiringPlayers, PeopleVec& io_retiringTrainers);
	void PreShrinkHofPlayers(PeopleVec& io_retiringPlayers);
	void PreShrinkHofTrainers(PeopleVec& io_retiringTrainers);
	void EndSeasonUpdate(const bool i_isPlayer, PeopleVec& o_retiringPeople, PeopleVec& o_endContractPeople);
	
	static size_t NUMBER_OF_MEMBERS; //unique id for trainers and players
	static const unsigned int BIG_SLOT_MEMBERS;
	static const unsigned int SMALL_SLOT_MEMBERS;

	ServiceProvider* m_sp;

	PeopleVec m_busyPlayers;
	PeopleVec m_freePlayers;

	PeopleVec m_busyTrainers;
	PeopleVec m_freeTrainers;

	PeopleVec m_hof;
};

inline size_t PeopleManager::GetLastID() const
{
	return NUMBER_OF_MEMBERS;
}

inline size_t PeopleManager::GetNewID()
{
	return ++NUMBER_OF_MEMBERS;
}

inline const PeopleVec& PeopleManager::GetBusyVec(const bool i_isPlayer) const
{
	return i_isPlayer ? m_busyPlayers : m_busyTrainers;
}

inline const PeopleVec& PeopleManager::GetFreeVec(const bool i_isPlayer) const
{
	return i_isPlayer ? m_freePlayers : m_freeTrainers;
}

inline const PeopleVec& PeopleManager::GetFreeVec(const bool i_isPlayer, const size_t i_minimumFree)
{
	PeopleVec& theVec = i_isPlayer ? m_freePlayers : m_freeTrainers;
	while(theVec.size() < i_minimumFree)
		GenerateNewSlot(BIG_SLOT_MEMBERS, i_isPlayer);
	return theVec;
}

inline const PeopleVec& PeopleManager::GetHofVec() const
{
	return m_hof;	
}

